package com.qf.controller;

import com.alibaba.druid.util.StringUtils;
import com.qf.captcha.CaptchaCodeManager;
import com.qf.pojo.DtsAdmin;
import com.qf.service.DtsPermissionService;
import com.qf.service.DtsRoleService;
import com.qf.util.*;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/admin/auth")

/**
 * 端口号
 * @CrossOrigin("http://localhost")
 */
public class AdminAuthController {
    @Autowired
    DtsPermissionService permissionService;
    @Autowired
    DtsRoleService roleService;

    /**
     * 登录成功后获取用户信息
     * @return
     */
    @RequestMapping("/info")
    public Object info(){
        Subject subject = SecurityUtils.getSubject();
        DtsAdmin admin = (DtsAdmin) subject.getPrincipal();

        Set<String> roles = roleService.findRolesByIds(admin.getRoleIds());
        Set<String> perms = permissionService.findPermsByIds(admin.getRoleIds());

        //封装用户信息
        Map<String,Object> data = new HashMap<>();
        data.put("roles",roles);
        data.put("perms",perms);
        data.put("nama",admin.getUsername());
        data.put("avatar",admin.getAvatar());
        return ResponseUtil.ok(data);
    }
    /**
     * 效验验证码
     * @param map
     * @return
     */
    @RequestMapping("/login")
    public Object login(@RequestBody Map<String,String> map, HttpSession session){
        String username = map.get("username");
        String password = map.get("password");
        String code = map.get("code");
        String uuid = map.get("uuid");

        if (StringUtils.isEmpty(username)
                || StringUtils.isEmpty(password)
                || StringUtils.isEmpty(code)
                || StringUtils.isEmpty(uuid)){

            return ResponseUtil.badArgument();
        }

        //获取验证码
        String cachedCaptcha = CaptchaCodeManager.getCachedCaptcha(uuid);
        //用户输入的验证码和本地源提供的验证码不相等 返回错误信息
        if (!code.equalsIgnoreCase(cachedCaptcha)){
            return AdminResponseUtil.fail(AdminResponseCode.AUTH_CAPTCHA_ERROR);
        }

        //开始认证
        Subject subject = SecurityUtils.getSubject();
        //创建token
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        //执行登录功能
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            return ResponseUtil.fail(-1,"未知的账户");
        }catch (LockedAccountException e) {
            e.printStackTrace();
            return ResponseUtil.fail(-1,"账户已锁定");
        }catch (CredentialsException e) {
            e.printStackTrace();
            return ResponseUtil.fail(-1,"密码错误");
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return ResponseUtil.fail(-1,"认证错误");
        }

        //获取session
        String data = session.getId();
        return ResponseUtil.ok(data);
    }

    /**
     * 获取验证码
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/captchaImage")
    public Object captchaImage(HttpServletResponse response) throws IOException {
        //调用工具类中的方法-使用系统默认字符源生成验证码
        String code = VerifyCodeUtils.generateVerifyCode(2);
        //生成 uuid， 验证码 唯一的标识
        String uuid = UUID.randomUUID().toString();
        //在缓存区 存储验证码
        CaptchaCodeManager.addToCache(uuid, code, 10);
        //输出流
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        //输出图片
        VerifyCodeUtils.outputImage(100, 40,outputStream  ,code );

        Map<String, Object> data  = new HashMap<>();
        data.put("img", Base64.encode(outputStream.toByteArray()));
        data.put("uuid", uuid);

        return ResponseUtil.ok(data);
    }
}
